# this script produces example plots of oligarch ownership networks
# (Figure 1 in the paper)

pacman::p_load(ggraph, tidygraph, igraph, grid, gridExtra, tidyverse, tidylog, 
               ggplot2, haven, stringi)

search_date <- "04012004"

# build network graph from list of ownership links for oligarch-controlled firms
source("create_network_Delo_UP.R")

# function to produce a network plot
build_group_plot <- function(group_name, oligarch_label,
                             random_seed,
                             color_nodes = T) {
  
  # oligarch identifier code
  oligarch_code <- all.ids %>%
    filter(entity_name == oligarch_label) %>%
    pull(id)
  
  # keep vertices related to the corresponding oligarch group
  group.graph.ids <- all.ids[, c("id", "category", "entity_name", 
                                 "oligarch", group_name)]
  colnames(group.graph.ids)[ncol(group.graph.ids)] <- paste("group") 
  group.graph.ids <- group.graph.ids %>% 
    filter(group == 1,
           !(id %in% not_connected))
  
  # keep edges related to the corresponding oligarch group
  group.graph.edges <- all.edges %>% 
    filter(owner %in% group.graph.ids$id,
           sub %in% group.graph.ids$id) %>%
    select(-step)
  
  # build network graph for the specified oligarch group 
  group.graph <- graph_from_data_frame(d = group.graph.edges, 
                                       directed = T, 
                                       vertices = group.graph.ids)
  
  # label vertices based on category
  V(group.graph)[names(V(group.graph)) == oligarch_code]$category <- 
    "Oligarch"
  V(group.graph)[V(group.graph)$category == "Individual"]$category <- 
    "Other individual"
  V(group.graph)[names(V(group.graph)) %in% Delo_UP_firm_list]$category <- 
    "Delo/UP firm"
  V(group.graph)[V(group.graph)$category == 
                   "Ukrainian firm"]$category <- "Other Ukrainian firm"
  V(group.graph)$category <- factor(V(group.graph)$category, 
                                    levels = c("Delo/UP firm",
                                               "Other Ukrainian firm", 
                                               "Foreign firm", 
                                               "Oligarch",
                                               "Other individual"), 
                                    ordered = T)
  
  # find paths to oligarch to highlight on the plot
  # check paths from the oligarch to all Delo/UP firms in the oligarch group
  firms_group <- Delo_UP_firm_list[Delo_UP_firm_list %in% V(group.graph)$name]
  spaths_olig <- shortest_paths(group.graph, oligarch_code, 
                                firms_group,
                                mode = "out")
  
  # keep only paths that actually lead to the oligarch
  spaths_olig_direct <- spaths_olig$vpath[map(spaths_olig$vpath, length) > 0]
  
  # specify edges along direct paths
  edges_direct <- map_df(spaths_olig_direct,
                            split_paths_pairs) %>%
    distinct() %>%
    mutate(direct_path = "Direct paths to oligarch")
  all_edges_group <- as_edgelist(group.graph) %>%
    as_tibble() %>%
    rename(owner = V1, sub = V2) %>%
    left_join(edges_direct) %>%
    replace_na(list(direct_path = "Other paths"))
  
  # add this variable to the graph
  E(group.graph)$direct_path <- all_edges_group$direct_path

  # set node sizes for plotting
  V(group.graph)$size_group <- case_when(
    V(group.graph)$name == oligarch_code ~ "large",
    V(group.graph)$name %in% Delo_UP_firm_list ~ "medium",
    TRUE ~ "small")
  
  # set seed for better layout (selected via trial and error)
  set.seed(random_seed)
  
  # plot
  if (color_nodes) {
    group.plot <- ggraph(group.graph, layout = "igraph", algorithm = "nicely") + 
      geom_node_point(aes(size = category,
                          color = category,
                          shape = category),
                      alpha = 0.8) +
      scale_colour_manual(name = "",
                          labels = c("Delo/UP firm",
                                     "Other Ukrainian firm",
                                     "Foreign firm",
                                     "Oligarch",
                                     "Other individual"),
                          values = c("#984ea3",
                                     "#984ea3",
                                     "#e41a1c",
                                     "#000000",
                                     "gray60"))
  } else {
    group.plot <- ggraph(group.graph, layout = "igraph", algorithm = "nicely") + 
      geom_node_point(aes(size = category,
                          shape = category),
                      alpha = 0.8)
  }
  
  group.plot <- group.plot +
    scale_size_manual(name = "", 
                      labels = c("Delo/UP firm",
                                 "Other Ukrainian firm", 
                                 "Foreign firm",
                                 "Oligarch",
                                 "Other individual"),
                      values = c(4, 2, 2, 8, 2)) +
    scale_shape_manual(name = "", 
                       labels = c("Delo/UP firm",
                                  "Other Ukrainian firm", 
                                  "Foreign firm",
                                  "Oligarch",
                                  "Other individual"),
                       values = c(19, 19, 15, 18, 17)) +
    geom_edge_link(aes(colour = direct_path,
                       width = direct_path),
                   alpha = 0.8,
                   start_cap = circle(1.5, 'mm'),
                   end_cap = circle(1.5, 'mm')) +
    scale_edge_colour_manual(name = "",
                               labels = c("Ownership leading to oligarch",
                                          "Other ownership link"),
                               values = c("gray0", "gray80")) +
    scale_edge_width_manual(name = "",
                            labels = c("Ownership leading to oligarch",
                                       "Other ownership link"),
                            values = c(0.8, 0.3)) +
    guides(shape = guide_legend(override.aes = list(size = c(4, 2, 2, 5, 2)))) +
    theme_graph(background = "white", base_family = 'Helvetica') + 
    theme(legend.key = element_rect(size = 5, color = "white"),
          legend.key.size = unit(1.8, 'lines'),
          legend.position = "bottom",
          legend.box = "vertical",
          legend.text = element_text(size = 19))
  
  return(group.plot)
}

# function to arrange two plots with the same legend
grid_arrange_shared_legend <-
  function(...,
           ncol = length(list(...)),
           nrow = 1,
           position = c("bottom", "right")) {
    
    plots <- list(...)
    position <- match.arg(position)
    g <-
      ggplotGrob(plots[[1]] + theme(legend.position = position))$grobs
    legend <- g[[which(sapply(g, function(x)
      x$name) == "guide-box")]]
    lheight <- sum(legend$height)
    lwidth <- sum(legend$width)
    gl <- lapply(plots, function(x)
      x + theme(legend.position = "none"))
    gl <- c(gl, ncol = ncol, nrow = nrow)
    
    combined <- switch(
      position,
      "bottom" = arrangeGrob(
        do.call(arrangeGrob, gl),
        legend,
        ncol = 1,
        heights = unit.c(unit(1, "npc") - lheight, lheight)
      ),
      "right" = arrangeGrob(
        do.call(arrangeGrob, gl),
        legend,
        ncol = 2,
        widths = unit.c(unit(1, "npc") - lwidth, lwidth)
      )
    )
    
    grid.newpage()
    grid.draw(combined)
    
    # return gtable invisibly
    invisible(combined)
    
  }

split_paths_pairs <- function(node_list) {
  edge_list <- names(node_list)
  return(tibble(owner = edge_list[1:(length(edge_list) - 1)],
                sub = edge_list[2:length(edge_list)]))
}

# find firms that don't have connections to other nodes in the network graph
# to omit them from the plot
not_connected <- V(o.network.D)[V(o.network.D)$degree == 0]$name

# a list of identifiers for Delo/UP firms (used in the function to build plot)
Delo_UP_firm_list <- all.ids %>%
  filter(step == 0) %>%
  pull(id)

# a list of identifiers for foreign firms
foreign_firms <- all.ids %>%
  filter(category == "Foreign firm") %>%
  pull(id)

# build plots for SCM and UkrPromInvest
plot_scm_color <- build_group_plot("SCM", "RINAT AKHMETOV", 1422)
plot_upi_color <- build_group_plot("UkrPromInvest", "PETRO POROSHENKO", 71)

# combine two plots in the same figure
scm_upi <- grid_arrange_shared_legend(plot_upi_color, plot_scm_color)

ggsave(paste0("Results/Figure_1.pdf"),
       scm_upi,
       width = 40, height = 20, units = "cm")
